package com.baiduspring.web.search;

import com.baiduspring.function.elasticsearch.ElasticsearchHandle;
import com.baiduspring.function.elasticsearch.operation.QueryInput;
import com.baiduspring.function.elasticsearch.operation.QueryResultsOutput;
import com.baiduspring.service.specialcolumn.SpecialColumnIndexEnum;
import com.baiduspring.utils.date.DateUtils;
import com.baiduspring.utils.security.Base64Utils;
import com.baiduspring.vo.SearchResultsVO;
import com.baiduspring.web.user.LoginStatus;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

/**
 * 全文搜索控制器
 *
 * @author xiongyan
 */
@RestController
@Scope("prototype")
@RequestMapping("/search")
@Slf4j
public class SearchController {
    /**
     * 进入搜索首页
     *
     * @param request 参数
     * @return 返回视图
     */
    @GetMapping
    public ModelAndView indexView(HttpServletRequest request) {
        ModelAndView view = new ModelAndView("search/index");
        LoginStatus.status(request, view);
        return view;
    }

    @GetMapping("/result")
    public ModelAndView resultsView(HttpServletRequest request, String wd, Integer currentPage) {
        ModelAndView view = new ModelAndView("search/result");

        try {
            wd = URLDecoder.decode(Base64Utils.decode(wd), "utf-8");
        } catch (UnsupportedEncodingException e) {
            log.error("转码错误：{}", e);
        }

        view.addObject("wd", wd);

        LoginStatus.status(request, view);

        return this.returnSearchView(view, wd, currentPage);
    }

    private ModelAndView returnSearchView(ModelAndView modelAndView, String keywords, Integer currentPage) {
        long start = System.currentTimeMillis();
        currentPage = Objects.isNull(currentPage) ? 0 : currentPage;

        modelAndView.addObject("currentPage", currentPage);

        Optional<QueryResultsOutput> optional = this.search(keywords, currentPage);
        optional.ifPresent(output -> modelAndView.addObject("results", output));

        modelAndView.addObject("time", DateUtils.ms2second(System.currentTimeMillis() - start));
        return modelAndView;
    }

    private Optional<QueryResultsOutput> search(String keywords, int currentPage) {
        QueryInput input = new QueryInput();
        String[] indies = {SpecialColumnIndexEnum.SPECIAL_COLUMN_BLOG_INDEX.getValue()};
        String[] types = {SpecialColumnIndexEnum.SPECIAL_COLUMN_BLOG_TYPE.getValue()};

        String[] filterFields = {
                "title",
                "contentTxt"
        };
        String[] highlightFields = {
                "title",
                "contentTxt"
        };

        Map<String, Class> outputFields = Maps.newHashMap();
        outputFields.put("title", String.class);
        outputFields.put("content", String.class);
        outputFields.put("contentTxt", String.class);
        outputFields.put("authorAccount", Long.class);
        outputFields.put("uriMark", Long.class);

        input.setIndices(indies);
        input.setTypes(types);
        input.setKeywords(keywords);
        input.setFilterFields(filterFields);
        input.setHighlightFields(highlightFields);
        input.setOutputFields(outputFields);
        input.setCurrentPage(currentPage);
        input.setPageSize(10);

        return ElasticsearchHandle.instance().search(input, false, SearchResultsVO.class);
    }

}
